import React from 'react';
import ProtoTypes from 'prop-types';
import { Table, Button, Search, Tag, Modal, Balloon, Message } from '@teamix/ui';
import { YunxiaoIcon } from '@alife/devops-ui';
import './index.scss';
import VisibilitySelect from 'components/accessSelect/normal';
import { checkImportProjectName } from 'api/index.js';
import exceed from 'utils/apimap';
import TableCellOverlay from './overlay1';
import AccountMessage from 'components/importProjectModal/accountMessage';
import CONSTANTS from 'utils/constants.js';
import ListLoading from 'atComponents/ListLoading';
import ListEmpty from 'atComponents/ListEmpty';
import track, { enterModal } from 'utils/track';
import utils from 'utils';
import docs from 'utils/docs';
import { navigateOpen } from 'utils/router';
import intl from '../../locale';

const prefix = 'import-project-list';
const tableHeaders = {
  import_repo_name: '代码库路径',
  new_repo_name: 'Codeup 代码库路径',
  visibility_level: intl.get({
    id: 'code-assets.components.importProjectListModal.Openness',
    defaultMessage: '公开性',
  }),

  import_repo_size: intl.get({
    id: 'code-assets.components.importProjectListModal.CodeLibrarySize',
    defaultMessage: '代码库大小',
  }),

  import_status: intl.get({
    id: 'code-assets.components.importProjectListModal.ImportStatus',
    defaultMessage: '导入状态',
  }),

  actions: intl.get({
    id: 'code-assets.components.importProjectListModal.Operation',
    defaultMessage: '操作',
  }),
};

const NOT_IMPORT = 'not_import';
const CANCEL = 'cancel';
const WAITING = 'waiting';
const IMPORTING = 'importing';
const FAIL = 'fail';
const SUCCESS = 'success';
const STOPPING = 'stopping';
const STOPPED = 'stopped';
const statusesObj = {
  [NOT_IMPORT]: intl.get({
    id: 'code-assets.components.importProjectListModal.NotImported',
    defaultMessage: '未导入',
  }),

  [CANCEL]: intl.get({
    id: 'code-assets.components.importProjectListModal.NotImported',
    defaultMessage: '未导入',
  }),

  [WAITING]: intl.get({
    id: 'code-assets.components.importProjectListModal.Queuing',
    defaultMessage: '排队中',
  }),

  [IMPORTING]: intl.get({
    id: 'code-assets.components.importProjectListModal.Importing',
    defaultMessage: '导入中',
  }),

  [FAIL]: intl.get({
    id: 'code-assets.components.importProjectListModal.ImportFailed',
    defaultMessage: '导入失败',
  }),

  [SUCCESS]: intl.get({
    id: 'code-assets.components.importProjectListModal.ImportedSuccessfully',
    defaultMessage: '导入成功',
  }),

  [STOPPING]: intl.get({
    id: 'code-assets.components.importProjectListModal.Terminating',
    defaultMessage: '终止中',
  }),

  [STOPPED]: intl.get({
    id: 'code-assets.components.importProjectListModal.Terminated',
    defaultMessage: '已终止',
  }),
};

const visiblityLevelObj = {
  0: intl.get({
    id: 'code-assets.components.importProjectListModal.PrivateVisibleOnlyToMembers',
    defaultMessage: '私有(仅代码库成员可见)',
  }),

  10: intl.get({
    id: 'code-assets.components.importProjectListModal.VisibleToEnterpriseAccessibleTo',
    defaultMessage: '企业可见(企业内成员可访问)',
  }),
};

const maxListLength = 1000;

// 暂时先支持自建gitlab, 类型对应名称
const { PLATFORM_TYPES } = CONSTANTS;
const trackMap = {
  PRIVATE_GITLAB: {
    importList: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'self-built gitlab',
      control: 'import repo by top button',
    },

    importSingle: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'self-built gitlab',
      control: 'import repo by list button',
    },

    cancelImport: {
      action: 'cancel_import',
      page: 'Modal-ImportRepo List',
      type: 'import self-built gitlab',
      control: '',
    },

    retryImport: {
      action: 'retry_import',
      page: 'Modal-ImportRepo List',
      type: 'import self-built gitlab',
      control: '',
    },
  },

  GITLAB: {
    importList: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'gitlab',
      control: 'import repo by top button',
    },

    importSingle: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'gitlab',
      control: 'import repo by list button',
    },

    cancelImport: {
      action: 'cancel_import',
      page: 'Modal-ImportRepo List',
      type: 'import gitlab',
      control: '',
    },

    retryImport: {
      action: 'retry_import',
      page: 'Modal-ImportRepo List',
      type: 'import gitlab',
      control: '',
    },
  },

  GITHUB: {
    importList: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'github',
      control: 'import repo by top button',
    },

    importSingle: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'github',
      control: 'import repo by list button',
    },

    cancelImport: {
      action: 'cancel_import',
      page: 'Modal-ImportRepo List',
      type: 'import github',
      control: '',
    },

    retryImport: {
      action: 'retry_import',
      page: 'Modal-ImportRepo List',
      type: 'import github',
      control: '',
    },
  },

  ALIYUN: {
    importList: {
      action: 'import Repo',
      page: 'Modal-ImportRepo List',
      type: 'import code.aliyun',
      control: 'import repo by top button',
    },

    importSingle: {
      action: 'import Repo',
      page: 'Modal-ImportRepo List',
      type: 'import code.aliyun',
      control: 'import repo by list button',
    },

    cancelImport: {
      action: 'cancel_import',
      page: 'Modal-ImportRepo List',
      type: 'import code.aliyun',
      control: '',
    },

    retryImport: {
      action: 'retry_import',
      page: 'Modal-ImportRepo List',
      type: 'import code.aliyun',
      control: '',
    },
  },

  GITEE: {
    importList: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'gitee',
      control: 'import repo by top button',
    },

    importSingle: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'gitee',
      control: 'import repo by list button',
    },

    cancelImport: {
      action: 'cancel_import',
      page: 'Modal-ImportRepo List',
      type: 'import gitee',
      control: '',
    },

    retryImport: {
      action: 'retry_import',
      page: 'Modal-ImportRepo List',
      type: 'import gitee',
      control: '',
    },
  },

  CODING: {
    importList: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'coding',
      control: 'import repo by top button',
    },

    importSingle: {
      action: 'import_repo',
      page: 'Modal-ImportRepo List',
      type: 'coding',
      control: 'import repo by list button',
    },

    cancelImport: {
      action: 'cancel_import',
      page: 'Modal-ImportRepo List',
      type: 'import coding',
      control: '',
    },

    retryImport: {
      action: 'retry_import',
      page: 'Modal-ImportRepo List',
      type: 'import coding',
      control: '',
    },
  },
};

export default class ImportProjectListModal extends React.PureComponent {
  static propTypes = {
    accountInfo: ProtoTypes.object,
    closeModal: ProtoTypes.func,
    handleUnbind: ProtoTypes.func,
    // 是不是第一次进来， 第一次进来先三方代码库信息同步至Codeup，然后查列表；否则异步调用三方代码库信息同步至Codeup接口、查列表。
    // 根据get帐号接口获取无帐号则为第一次
    isFirst: ProtoTypes.bool,
  };

  static defaultProps = {
    accountInfo: {},
    closeModal: () => {},
    handleUnbind: () => {},
    isFirst: false,
  };

  constructor(props) {
    super(props);
    this.state = {
      selectedRowKeys: [],
      list: [],
      // isLoadingTable: true,
      isModalOpen: props.isModalOpen,
      // 重名id列表，显示重名
      repeatList: [],
      // 名称不合法列表,显示非法
      inValidateList: [],
      filterText: '',
      tableDataLoaded: false,
      visible_levels: [],
      display_levels: [],
      isLoadingSetting: false,
      isRefreshing: false,
      is_group_required: false,
      repo_visibility_level: [],
      errStateInfo: false,
    };

    // 定时查询
    this.timer = null;
    this.isComponentUnmouted = false;
  }

  componentDidMount() {
    const { isFirst } = this.props;
    // 获取公开性设置,再获取数据
    this.getOrganizationSetting(() => {
      // 此处是否有必要全部改成同步
      if (isFirst) {
        this.syncProjectList(isFirst, () => {
          this.getTableData();
        });
      } else {
        this.syncProjectList(isFirst);
        this.getTableData();
      }
    });
    // 打开列表弹窗也要去除url后面的信息
    const auto_bind = utils.getUrlSearchParam('auto_bind') || '';
    if (auto_bind) {
      window.history.replaceState({}, null, '/');
    }

    enterModal('Modal-ImportRepo List', {
      sendPV: false,
      sendPerf: false,
    });
    document.body.classList.add('no-min-width');
  }

  componentWillUnmount() {
    clearTimeout(this.timer);
    // 卸载时将异步操作终止
    this.isComponentUnmouted = true;
    document.body.classList.remove('no-min-width');
  }

  getOrganizationSetting = (cb) => {
    const { organization } = window.FORCE;
    this.setState({
      isLoadingSetting: true,
    });

    exceed
      .forceFetch({
        api: 'organization.repo.setting.get',
        params: {
          org_id: organization.id,
        },
      })
      .then((result) => {
        this.setState(
          {
            visible_levels: result.repo_visibility_level || [],
            display_levels: result.repo_display_level || [],
            is_group_required: result.is_group_required,
            repo_visibility_level: result.repo_visibility_level,
            isLoadingSetting: false,
          },

          () => {
            cb && cb();
          },
        );
      });
  };

  openTimer = () => {
    if (this.isComponentUnmouted) {
      return;
    }
    clearTimeout(this.timer);
    this.timer = setTimeout(() => {
      this.getTableData(true);
    }, 3000);
  };

  onClose = () => {
    this.setState({
      isModalOpen: false,
    });

    this.props.closeModal();
  };

  saveName = (value, import_repo_id, groupAccess = '') => {
    const { list, repeatList } = this.state;
    const projectList = [...list];
    projectList.forEach((item) => {
      if (item.import_repo_id === import_repo_id) {
        item.new_repo_name = value;
        item.groupAccess = groupAccess;
      }
    });
    const index = repeatList.findIndex((item) => {
      return item.id === import_repo_id;
    });
    if (index > -1) {
      repeatList.splice(index, 1);
    }
    this.setState({
      list: projectList,
      repeatList: [...repeatList],
    });
  };

  getVisibilityLevel = (item) => {
    if (item.visibility_level !== undefined) {
      return item.visibility_level;
    }
    const { display_levels } = this.state;
    const curLevels = display_levels.filter((v) => {
      return !item.groupAccess || (item.groupAccess && Number(item.groupAccess) < v);
    });
    return curLevels[0] !== undefined ? curLevels[0] : '';
  };

  checkAllPath = (list) => {
    const allPromise = list.map((item) => {
      return this.checkSinglePath(item);
    });

    Promise.all(allPromise).then((res) => {
      const repeatList =
        res.filter((item) => {
          return item;
        }) || [];
      this.setState({
        repeatList,
      });
    });
  };

  checkSinglePath = (item) => {
    const name = this.getNewRepoName(item);

    return new Promise((resolve) => {
      const { organization } = window.FORCE;
      const namespace_id = organization.namespace_id || '';
      const visibility_level = this.getVisibilityLevel(item);
      checkImportProjectName({ path: name, name: '', namespace_id, visibility_level })
        .then(() => {
          resolve();
        })
        .catch((err) => {
          resolve({
            status: err.status,
            id: item.import_repo_id,
            text: JSON.parse(err.responseText).cause || '',
          });
        });
    });
  };

  syncProjectList = (sync, cb) => {
    const platform_type = this.props.accountInfo.platform_type || '';
    exceed
      .fetch({
        api: 'projects.import.sync',
        params: {
          platform_type,
          async: !sync, // true 异步 false 同步
        },
      })
      .then((result) => {
        if (result.result) {
          cb && cb();
        } else {
          this.setState({
            isRefreshing: false,
          });
        }
      })
      .fail((err) => {
        this.setState({
          isRefreshing: false,
        });
        // https://aone.alibaba-inc.com/v2/req/35898177# 《大量库导入列表加载失败》
        if (err && err?.status >= 500) {
          this.setState({
            errStateInfo: true,
          });
        }

        console.error(err);
      });
  };

  sortList = (list) => {
    return list.sort((a, b) => {
      return new Date(b.gmt_create).getTime() - new Date(a.gmt_create).getTime();
    });
  };

  // 解析名称
  getNewRepoName = (item) => {
    if (item.new_repo_name) {
      // 有导入后id，则需要去除第一级
      if (item.new_repo_id) {
        return utils.getGroupPath(item.new_repo_path);
      } else {
        return item.new_repo_name;
      }
    } else {
      const oldName = item.import_repo_name;
      let text = '';
      if (oldName.includes('/')) {
        const arr = item.import_repo_name.split('/').map((t) => {
          return t.trim();
        });
        text = arr.join('/');
      } else {
        text = oldName;
      }
      return text || '';
    }
  };

  isInvalidRecord = (repeatList, import_repo_id) => {
    return (
      repeatList.findIndex((item) => {
        return item.id === import_repo_id;
      }) > -1
    );
  };

  getTableData = (isOnlyUpdateStatus) => {
    const { visible_levels, list } = this.state;
    const { accountInfo } = this.props;
    if (!isOnlyUpdateStatus) {
      this.setState({
        isLoadingTable: true,
        selectedRowKeys: [],
      });
    }
    // 清除定时器
    clearTimeout(this.timer);
    const allPromise = [
      IMPORTING,
      FAIL,
      SUCCESS,
      STOPPING,
      STOPPED,
      WAITING,
      NOT_IMPORT,
      CANCEL,
    ].map((status) => {
      return new Promise((resolve, reject) => {
        exceed
          .fetch({
            api: 'projects.import.list',
            data: {
              platform_type: accountInfo.platform_type,
              status,
            },
          })
          .then((result) => {
            resolve(result.slice(1));
          })
          .fail((err) => {
            reject(err);
          });
      });
    });
    Promise.all(allPromise)
      .then((responses) => {
        const [
          importingList,
          failList,
          successList,
          stoppingList,
          stoppedList,
          waitingList,
          notImportList,
          cancelImportList,
        ] = responses;
        const newImportingList = this.sortList(importingList);
        const newStoppingList = this.sortList(stoppingList);
        const newSuccessList = this.sortList(successList);
        const newFailList = this.sortList(failList);
        const newStoppedList = this.sortList(stoppedList);
        const inQueueList = [
          ...newImportingList,
          ...newStoppingList,
          ...newSuccessList,
          ...newFailList,
          ...newStoppedList,
        ];

        const outQueueList = [...waitingList, ...notImportList, ...cancelImportList].sort(
          (a, b) => {
            return a.new_repo_name - b.new_repo_name;
          },
        );

        // 数组去重
        const allList = [];
        const allListTmp = [...inQueueList, ...outQueueList];
        allListTmp.forEach((item) => {
          const index = allList.findIndex((item2) => {
            return item2.import_repo_id === item.import_repo_id;
          });
          if (index === -1) {
            allList.push(item);
          }
        });
        // 是否需要开启路径校验
        let needCheckAllPath = false;
        if (!isOnlyUpdateStatus) {
          // 没有导入后名称，则自动填写
          allList.forEach((item) => {
            item.new_repo_name = this.getNewRepoName(item);
            // 没有公开性则设置为可以设置的值的第一个
            if (item.visibility_level === undefined && visible_levels.length) {
              item.visibility_level = visible_levels[0];
            }
          });
          needCheckAllPath = true;
        } else {
          list.forEach((item) => {
            allList.forEach((newItem) => {
              // list包含当前newItem，编辑的名称根据上一次的数据计算，因为可能名称被编辑了；否则，根据自身计算
              const hasItem = list.some((singleItem) => {
                return singleItem.import_repo_id === newItem.import_repo_id;
              });
              if (!hasItem) {
                newItem.new_repo_name = this.getNewRepoName(newItem);
                if (newItem.visibility_level === undefined && visible_levels.length) {
                  newItem.visibility_level = visible_levels[0];
                }
              }
              if (item.import_repo_id === newItem.import_repo_id) {
                newItem.visibility_level = item.visibility_level;
                newItem.new_repo_name = this.getNewRepoName(item);
              }
            });
          });
          // 长度不相等 或者相等时又有new_repo_id没有且失败的库
          needCheckAllPath =
            allList.length !== list.length ||
            allList.some((item) => {
              return [STOPPED, FAIL].includes(item.import_status) && !item.new_repo_id;
            });
        }

        // 失败且无new_repo_id 或者未导入或者被取消的需要进行路径校验
        const needCheckList =
          allList.filter((item) => {
            return (
              item.import_status === NOT_IMPORT ||
              item.import_status === CANCEL ||
              ([STOPPED, FAIL].includes(item.import_status) && !item.new_repo_id)
            );
          }) || [];

        // 校验名称(未导入的和导入失败（含fail + stopped）没new_repo_id的)
        needCheckAllPath && this.checkAllPath(needCheckList);

        // 返回结果后，需要将不可选择的行从selectRowKeys去除
        const { selectedRowKeys, repeatList, inValidateList } = this.state;
        allList.forEach((item) => {
          const disabledSelect =
            this.isInvalidRecord(repeatList, item.import_repo_id) ||
            inValidateList.includes(item.import_repo_id) ||
            ([STOPPED, FAIL].includes(item.import_status) && item.new_repo_id) ||
            [IMPORTING, SUCCESS, WAITING, STOPPING].includes(item.import_status);
          if (disabledSelect) {
            const removeIndex = selectedRowKeys.indexOf(item.import_repo_id);
            selectedRowKeys.splice(removeIndex, 1);
          }
        });

        // 单独对waiting保持原有位置不变
        const newAllList = this.keepWaitingPositing(allList, list, isOnlyUpdateStatus);
        this.setState({
          isLoadingTable: false,
          list: newAllList,
          tableDataLoaded: true,
          isRefreshing: false,
          selectedRowKeys: [...selectedRowKeys],
        });

        // 每次获取表格后，打开定时器(数据中含有导入中、排队中、终止中时才开)
        const needTimer = allList.some((item) => {
          return [IMPORTING, WAITING, STOPPING].includes(item.import_status);
        });
        needTimer && this.openTimer();
      })
      .catch((err) => {
        console.error(err);
        this.setState({
          isLoadingTable: false,
        });

        // 报错也开启定时器
        const needTimer = list.some((item) => {
          return [IMPORTING, WAITING, STOPPING].includes(item.import_status);
        });
        needTimer && this.openTimer();
      });
  };

  keepWaitingPositing = (allList, list, isOnlyUpdateStatus) => {
    if (!isOnlyUpdateStatus) {
      return allList;
    }

    allList.forEach((item1, index1) => {
      list.forEach((item2, index2) => {
        if (item1.import_repo_id === item2.import_repo_id && item1.import_status === WAITING) {
          allList.splice(index1, 1);
          allList.splice(index2, 0, item1);
        }
      });
    });
    return allList;
  };

  // isNeedCheck 是否需要进行校验
  handleSelect = (visibility_level, record, isNeedCheck) => {
    const curList = [...this.state.list];
    const { repeatList } = this.state;
    curList.forEach((item) => {
      if (record.import_repo_id === item.import_repo_id) {
        item.visibility_level = visibility_level;
      }
    });
    const curItem = curList.find((item) => item.import_repo_id === record.import_repo_id);
    if (isNeedCheck) {
      this.checkSinglePath(curItem)
        .then((result) => {
          const index = repeatList.findIndex((repeatItem) => {
            return repeatItem.id === curItem.import_repo_id;
          });
          if (result) {
            if (index > -1) {
              repeatList.splice(index, 1, result);
            } else {
              repeatList.push(result);
            }
          } else if (index > -1) {
            repeatList.splice(index, 1);
          }
          this.setState({
            repeatList,
            list: curList,
          });
        })
        .catch((err) => {
          console.error(err);
          this.setState({
            list: curList,
          });
        });
    }
  };

  renderImportRepoName = (value, index, record) => {
    const trigger = (
      <div className="table-cell-one-line">
        <a href={record.import_repo_path} target="_blank" rel="noreferrer">
          {value}
        </a>
      </div>
    );

    return (
      <Balloon.Tooltip trigger={trigger} align="t">
        {value}
      </Balloon.Tooltip>
    );
  };

  // 手动修改状态
  changeProjectImportStatus = (ids) => {
    if (this.isComponentUnmouted) {
      return;
    }
    if (!Array.isArray(ids)) {
      return;
    }
    // eslint-disable-next-line react/no-access-state-in-setstate
    const projectList = [...this.state.list];
    projectList.forEach((item) => {
      if (ids.includes(item.import_repo_id)) {
        // 导入 变成 排队, 新增取消状态，和未导入一致
        if (item.import_status === NOT_IMPORT || item.import_status === CANCEL) {
          item.import_status = WAITING;
        }
        // 取消排队 排成 未导入
        if (item.import_status === WAITING) {
          item.import_status = NOT_IMPORT;
        }
        // 导入中 变成 终止中
        if (item.import_status === IMPORTING) {
          item.import_status = STOPPING;
        }
      }
    });
    this.setState({
      list: projectList,
    });
  };

  renderNewImportName = (value, index, record) => {
    // 未导入需要选择 或者失败的库无new_repo_id也可编辑
    if (
      record.import_status === NOT_IMPORT ||
      record.import_status === CANCEL ||
      ([STOPPED, FAIL].includes(record.import_status) && !record.new_repo_id)
    ) {
      const { repeatList, is_group_required } = this.state;
      const isRepeat = this.isInvalidRecord(repeatList, record.import_repo_id);
      const invalidInfo = repeatList.find((item) => {
        return item.id === record.import_repo_id;
      });

      return (
        <TableCellOverlay
          visibility_level={this.getVisibilityLevel(record)}
          value={value}
          is_group_required={is_group_required}
          invalidInfo={invalidInfo}
          isRepeat={isRepeat}
          import_repo_id={record.import_repo_id}
          saveName={this.saveName}
        />
      );
    }
    const trigger = <div className="table-cell-one-line">{value}</div>;
    return (
      <Balloon.Tooltip trigger={trigger} align="t">
        {value}
      </Balloon.Tooltip>
    );
  };

  renderVisibilityLevel = (value, index, record) => {
    const { visible_levels, display_levels, isLoadingSetting, repo_visibility_level } = this.state;
    // 未导入需要选择 或者失败的库无new_repo_id也可编辑,没有可见性也要禁用
    if (
      record.import_status === NOT_IMPORT ||
      record.import_status === CANCEL ||
      ([STOPPED, FAIL].includes(record.import_status) && !record.new_repo_id)
    ) {
      return (
        <VisibilitySelect
          onChange={(visibility_level) => {
            this.handleSelect(visibility_level, record, true);
          }}
          visible_levels={visible_levels}
          display_levels={display_levels}
          isLoadingSetting={isLoadingSetting}
          hasBorder={false}
          value={value}
          groupAccess={record.groupAccess}
          repo_visibility_level={repo_visibility_level}
          style={{ width: '100%' }}
          initValueFn={(visibility_level) => {
            this.handleSelect(visibility_level, record, false);
          }}
        />
      );
    }
    return <div style={{ padding: '0 8px' }}>{visiblityLevelObj[value]}</div>;
  };

  renderImportRepoSize = (value) => {
    if (value === 0) {
      return '0 MB';
    }

    if (!value || value < 0) {
      return intl.get({
        id: 'code-assets.components.importProjectListModal.UnknownSize',
        defaultMessage: '未知大小',
      });
    }

    if (value <= 5) {
      return '0 MB';
    }

    const repoSize = (value / 1024.0).toFixed(2);

    if (repoSize >= 1024) {
      const repoGBSize = (repoSize / 1024.0).toFixed(2);
      return `${repoGBSize} GB`;
    }

    return `${repoSize} MB`;
  };

  renderStatus = (value, index, record) => {
    if (value === NOT_IMPORT || value === CANCEL) {
      return (
        <Tag>
          <YunxiaoIcon type="information-line" /> {statusesObj[NOT_IMPORT]}
        </Tag>
      );
    }
    if (value === WAITING) {
      return (
        <Tag>
          <YunxiaoIcon type="clock-line" /> {statusesObj[WAITING]}
        </Tag>
      );
    }
    if (value === IMPORTING) {
      return (
        <Tag type="primary">
          <YunxiaoIcon type="refresh-line" /> {statusesObj[IMPORTING]}
        </Tag>
      );
    }
    if (value === STOPPING) {
      return (
        <Tag type="primary">
          <YunxiaoIcon type="refresh-line" /> {statusesObj[STOPPING]}
        </Tag>
      );
    }
    if (value === FAIL || value === STOPPED) {
      if (
        record.message &&
        record.message.indexOf(
          intl.get({
            id: 'code-assets.components.importProjectListModal.UnableToConnect',
            defaultMessage: '无法连通',
          }),
        ) >= 0
      ) {
        return (
          <>
            <Tag color="red">
              <YunxiaoIcon type="delete-fill" /> {statusesObj[FAIL]}
            </Tag>
            <Balloon
              closable={false}
              align="t"
              trigger={
                <YunxiaoIcon type="information-line" style={{ marginLeft: 4, color: '#1b9aee' }} />
              }
            >
              {intl.get({
                id: 'code-assets.components.importProjectListModal.UnableToConnectToThe',
                defaultMessage: '代码库地址无法连通，',
              })}

              <a
                href="https://gitlab.com/gitlab-org/gitlab-foss/-/blob/master/config/gitlab.yml.example#L33"
                target="_blank"
                rel="noreferrer"
              >
                {intl.get({
                  id: 'code-assets.components.importProjectListModal.CommonSolutions',
                  defaultMessage: '常见处理方案',
                })}
              </a>
            </Balloon>
          </>
        );
      } else {
        return (
          <>
            <Tag color="red">
              <YunxiaoIcon type="delete-fill" /> {statusesObj[FAIL]}
            </Tag>
            <Balloon.Tooltip
              align="t"
              trigger={
                <YunxiaoIcon type="information-line" style={{ marginLeft: 4, color: '#1b9aee' }} />
              }
            >
              {record.message}
            </Balloon.Tooltip>
          </>
        );
      }
    }
    return (
      <Tag color="green">
        <YunxiaoIcon type="clock-line" /> {statusesObj[SUCCESS]}
      </Tag>
    );
  };

  renderActions = (value, index, record) => {
    const { repeatList, inValidateList } = this.state;
    const { accountInfo } = this.props;
    const disabled =
      this.isInvalidRecord(repeatList, record.import_repo_id) ||
      inValidateList.includes(record.import_repo_id) ||
      record.visibility_level === '';
    // 失败且无new_repo_id，有重试和进入库，无需路径校验
    // 未导入 和导入失败（fail 和 stopped）时无new_repo_id则显示导入按钮，此时需要进行路径校验；其他情况不检验

    if (record.vcs_type === 'svn') {
      return (
        <Balloon.Tooltip
          trigger={
            <Button type="normal" size="xs" disabled>
              {intl.get({
                id: 'code-assets.components.importProjectListModal.Import',
                defaultMessage: '导入',
              })}
            </Button>
          }
          align="t"
          popupStyle={{ width: 200 }}
        >
          {intl.get({
            id: 'code-assets.components.importProjectListModal.ReturnToTheImportType',
            defaultMessage: '请返回导入类型页面，选择「SVN」仓库导入',
          })}
        </Balloon.Tooltip>
      );
    }

    if (
      record.import_status === NOT_IMPORT ||
      record.import_status === CANCEL ||
      ([STOPPED, FAIL].includes(record.import_status) && !record.new_repo_id)
    ) {
      // 如果是需要重试的，接口返回了message的，需要对按钮增加提示
      const { import_repo_size } = record;
      if (import_repo_size > 2097152) {
        return (
          <Balloon
            closable={false}
            align="t"
            trigger={
              <Button
                type="normal"
                size="xs"
                disabled
                onClick={() => {
                  if (disabled) {
                    return;
                  }
                  if (record.import_status === NOT_IMPORT || record.import_status === CANCEL) {
                    track(trackMap[accountInfo.platform_type].importSingle);
                  } else {
                    track(trackMap[accountInfo.platform_type].retryImport);
                  }
                  this.importList([record.import_repo_id]);
                }}
              >
                {record.import_status === NOT_IMPORT || record.import_status === CANCEL
                  ? intl.get({
                      id: 'code-assets.components.importProjectListModal.Import',
                      defaultMessage: '导入',
                    })
                  : intl.get({
                      id: 'code-assets.components.importProjectListModal.TryAgain',
                      defaultMessage: '重试',
                    })}
              </Button>
            }
          >
            {intl.get({
              id: 'code-assets.components.importProjectListModal.TheCodeLibraryIsToo',
              defaultMessage: '代码库过大，请通过命令行本地推送或使用',
            })}

            <a href={docs('importTool')} target="_blank" rel="noreferrer">
              {intl.get({
                id: 'code-assets.components.importProjectListModal.ImportTool',
                defaultMessage: '导入工具',
              })}
            </a>
          </Balloon>
        );
      }
      const btn = (
        <Button
          type="normal"
          size="xs"
          disabled={disabled}
          onClick={() => {
            if (disabled) {
              return;
            }
            if (record.import_status === NOT_IMPORT || record.import_status === CANCEL) {
              track(trackMap[accountInfo.platform_type].importSingle);
            } else {
              track(trackMap[accountInfo.platform_type].retryImport);
            }
            this.importList([record.import_repo_id]);
          }}
        >
          {record.import_status === NOT_IMPORT || record.import_status === CANCEL
            ? intl.get({
                id: 'code-assets.components.importProjectListModal.Import',
                defaultMessage: '导入',
              })
            : intl.get({
                id: 'code-assets.components.importProjectListModal.TryAgain',
                defaultMessage: '重试',
              })}
        </Button>
      );

      if (record.message) {
        return (
          <Balloon.Tooltip align="t" trigger={btn}>
            {record.message}
          </Balloon.Tooltip>
        );
      }
      return btn;
    }
    if (record.import_status === WAITING) {
      return (
        <Button
          type="normal"
          warning
          size="xs"
          onClick={() => {
            track(trackMap[accountInfo.platform_type].cancelImport);
            this.handleCancel(record.import_repo_id);
          }}
        >
          {intl.get({
            id: 'code-assets.components.importProjectListModal.CancelImport',
            defaultMessage: '取消导入',
          })}
        </Button>
      );
    }
    if (record.import_status === IMPORTING) {
      const stopTriggerBtn = (
        <Button
          type="normal"
          warning
          size="xs"
          onClick={() => {
            this.handleStop(record.import_repo_id);
          }}
        >
          {intl.get({
            id: 'code-assets.components.importProjectListModal.TerminateImport',
            defaultMessage: '终止导入',
          })}
        </Button>
      );

      return (
        <Balloon.Tooltip trigger={stopTriggerBtn} align="t">
          {intl.get({
            id: 'code-assets.components.importProjectListModal.ImportWillFailAfterClicking',
            defaultMessage: '点击后导入将会失败，请谨慎操作',
          })}
        </Balloon.Tooltip>
      );
    }
    if (record.import_status === STOPPING) {
      return (
        <Button type="normal" size="xs" disabled>
          {intl.get({
            id: 'code-assets.components.importProjectListModal.Terminating',
            defaultMessage: '终止中',
          })}
        </Button>
      );
    }
    if ([STOPPED, FAIL].includes(record.import_status) && record.new_repo_id) {
      const retryTrigger = (
        <Button
          type="normal"
          size="xs"
          onClick={() => {
            this.importList([record.import_repo_id], 'retry');
            track(trackMap[accountInfo.platform_type].retryImport);
          }}
        >
          {intl.get({
            id: 'code-assets.components.importProjectListModal.TryAgain',
            defaultMessage: '重试',
          })}
        </Button>
      );

      return (
        <React.Fragment>
          <Balloon.Tooltip trigger={retryTrigger} align="t">
            {record.message
              ? record.message
              : intl.get({
                  id: 'code-assets.components.importProjectListModal.IfYouFailToImport',
                  defaultMessage: '如多次尝试导入均失败，推荐您采用手动 clone/push 方式进行导入',
                })}
          </Balloon.Tooltip>

          <Button
            type="normal"
            style={{ marginLeft: 12 }}
            size="xs"
            onClick={() => {
              navigateOpen(`/${record.new_repo_path}`);
            }}
          >
            {intl.get({
              id: 'code-assets.components.importProjectListModal.InboundAndOutbound',
              defaultMessage: '进入库',
            })}
          </Button>
        </React.Fragment>
      );
    }
    return (
      <Button
        type="normal"
        size="xs"
        onClick={() => {
          navigateOpen(`/${record.new_repo_path}`);
        }}
      >
        {intl.get({
          id: 'code-assets.components.importProjectListModal.InboundAndOutbound',
          defaultMessage: '进入库',
        })}
      </Button>
    );
  };

  onChange = (selectedRowKeys) => {
    this.setState({
      selectedRowKeys,
    });
  };

  importList = (ids, type) => {
    clearTimeout(this.timer);
    const { list } = this.state;
    const { accountInfo } = this.props;
    const importList = list.filter((item) => {
      return ids.includes(item.import_repo_id);
    });
    const projectList = importList.map((item) => {
      return {
        id: item.import_repo_id,
        path: item.new_repo_name,
        visibility_level: item.visibility_level || 0,
        platform_type: accountInfo.platform_type,
      };
    });
    exceed
      .fetch({
        api: 'projects.list.import',
        data: { projectList },
      })
      .then((result) => {
        this.getTableData(true);
        this.changeProjectImportStatus(ids);
        if (!result.result && type === 'retry') {
          Message.error({
            title: intl.get({
              id: 'code-assets.components.importProjectListModal.RetryFailed',
              defaultMessage: '重试失败',
            }),
          });
        }
      })
      .fail((err) => {
        console.error(err);
      });
  };

  // 取消排队导入
  handleCancel = (id) => {
    clearTimeout(this.timer);
    exceed
      .fetch({
        api: 'projects.list.cancelImport',
        params: {
          projectId: id,
        },
      })
      .then(() => {
        this.getTableData(true);
      })
      .fail((err) => {
        console.error(err);
      });
  };

  handleStop = (id) => {
    clearTimeout(this.timer);
    exceed
      .fetch({
        api: 'projects.list.stopImport',
        params: {
          projectId: id,
        },
      })
      .then(() => {
        this.getTableData(true);
        this.changeProjectImportStatus([id]);
      })
      .fail((err) => {
        console.error(err);
      });
  };

  unbindCallback = () => {
    this.setState({
      isModalOpen: false,
    });

    // 解绑后
    clearTimeout(this.timer);
    this.props.handleUnbind();
    this.props.closeModal();
  };

  handleRefresh = () => {
    clearTimeout(this.timer);
    this.setState({
      isRefreshing: true,
    });

    this.syncProjectList(true, () => {
      this.getTableData();
    });
  };

  render() {
    const { accountInfo } = this.props;
    const {
      selectedRowKeys,
      isLoadingTable,
      list,
      isModalOpen,
      filterText,
      repeatList,
      inValidateList,
      tableDataLoaded,
      isRefreshing,
      errStateInfo,
    } = this.state;
    const platform_name =
      (accountInfo.platform_type &&
        PLATFORM_TYPES[accountInfo.platform_type] &&
        PLATFORM_TYPES[accountInfo.platform_type].name) ||
      '';

    if (!isModalOpen) {
      return null;
    }

    const curList = list.filter((item) => {
      return item.import_repo_name.includes(filterText) || item.new_repo_name.includes(filterText);
    });
    // 显示文案
    const noData = tableDataLoaded && !list.length;
    // 显示表格
    const showTable = tableDataLoaded && list.length;
    // 超过最大数
    const isTooLarge = curList.length > maxListLength;
    // 是否展示代码库大小
    const showRepoSize =
      accountInfo.platform_type === 'GITHUB' ||
      accountInfo.platform_type === 'GITLAB' ||
      accountInfo.platform_type === 'PRIVATE_GITLAB';

    return (
      <Modal
        onClose={this.onClose}
        onBack={this.onClose}
        hasArrow
        visible
        title={
          <div className={`${prefix}-title`}>
            <div className={`${prefix}-title-left`}>
              {intl.get(
                {
                  id: 'code-assets.components.importProjectListModal.ImportTheCodeLibraryFrom',
                  defaultMessage: '从 {platformName} 导入代码库',
                },

                { platformName: platform_name },
              )}
            </div>
            <div className={`${prefix}-title-split`} />
            <div className={`${prefix}-title-right`}>
              <AccountMessage
                accountInfo={accountInfo}
                unbindCallback={this.unbindCallback}
                origin="list"
              />
            </div>
          </div>
        }
        className={`${prefix}-modal`}
      >
        <div className={`${prefix}-content`}>
          <div className={`${prefix}-top`}>
            {accountInfo &&
            (accountInfo.platform_type === 'PRIVATE_GITLAB' ||
              accountInfo.platform_type === 'GITLAB') ? (
                <div className={`${prefix}-top-left-other`}>
                  <div className="other-icon">
                    <YunxiaoIcon type="warning-fill" />
                  </div>
                  <div className="other-desc">
                    <div className={`${prefix}-top-left-span`}>
                      1.
                      以下仅展示权限为库成员的代码库，如需导入非库成员但有读权限的代码库，请使用本地批量
                      <a
                        style={{ display: 'contents' }}
                        target="_blank"
                        href={docs('importTool')}
                        rel="noreferrer"
                      >
                        导入工具
                      </a>
                      （如管理员账号搬站场景)
                    </div>
                    <div className={`${prefix}-top-left-span`}>
                      2. 当导入 Codeup
                      代码库所在代码组路径不存在且有创建代码组权限时，将会自动创建企业可见的代码组
                    </div>
                  </div>
                </div>
            ) : (
              <div className={`${prefix}-top-left`}>
                <YunxiaoIcon type="warning-fill" />{' '}
                <span>
                  {intl.get({
                    id: 'code-assets.components.importProjectListModal.NoteIfTheCodeGroup',
                    defaultMessage:
                      '提示：当输入的 Codeup 代码库所在代码组路径不存在且有创建代码组权限时，将会自动创建企业可见的代码组',
                  })}
                </span>
              </div>
            )}
            <div className={`${prefix}-top-right`}>
              <Button
                type="normal"
                className={`${prefix}-top-right-refresh`}
                onClick={this.handleRefresh}
                loading={isRefreshing}
              >
                {intl.get({
                  id: 'code-assets.components.importProjectListModal.Refresh',
                  defaultMessage: '刷新',
                })}
              </Button>
              <Search
                style={{ width: '300px' }}
                placeholder={intl.get({
                  id: 'code-assets.components.importProjectListModal.SearchForCodeLibrariesOr',
                  defaultMessage: '搜索代码库或组',
                })}
                onChange={(value) => {
                  this.setState({ filterText: value.trim() });
                }}
                value={filterText}
              />
            </div>
          </div>
          <div
            className="import-list-loading"
            style={{ display: !tableDataLoaded ? 'block' : 'none' }}
          >
            <ListLoading
              text={intl.get({
                id: 'code-assets.components.importProjectListModal.CodeBaseDataLoadingPlease',
                defaultMessage: '代码库数据加载中...  请稍候',
              })}
            />
          </div>
          <div style={{ display: noData ? 'block' : 'none' }} className="import-list-no-data">
            <ListEmpty
              content={
                errStateInfo
                  ? '获取代码库列表超时'
                  : intl.get({
                      id: 'code-assets.components.importProjectListModal.TheErrorMessageReturnedBecause',
                      defaultMessage: '在绑定帐号下未获取到代码库。',
                    })
              }
              size="large"
              imgType="fail"
              description={
                <div style={{ width: 450 }}>
                  {errStateInfo ? (
                    <div>
                      <div>错误原因：代码库数量过多或网络过慢</div>
                      <div>
                        解决方案：因网络原因导致超时，推荐使用本地
                        <a href={docs('importTool')} target="_blank" rel="noreferrer">
                          {intl.get({
                            id: 'code-assets.components.importProjectListModal.ImportTool',
                            defaultMessage: '导入工具',
                          })}
                        </a>
                        批量导入。
                      </div>
                    </div>
                  ) : (
                    <div>
                      {intl.get({
                        id: 'code-assets.components.importProjectListModal.TheListOfCodeLibraries',
                        defaultMessage: '存在以下原因可能造成代码库列表为空：',
                      })}

                      <br />
                      {intl.get({
                        id: 'code-assets.components.importProjectListModal.TheCodeLibraryWithMember',
                        defaultMessage:
                          '1.绑定帐号下不存在有成员权限的代码库。请您确认是否绑定了正确的帐号。',
                      })}

                      <br />
                      {intl.get({
                        id: 'code-assets.components.importProjectListModal.TheErrorMessageReturnedBecause.1',
                        defaultMessage:
                          '2.未授 Codeup 读取帐号下的代码库或授权失效。请您重新校验绑定帐号，确认授权 Codeup 获取代码库读取权限及授权有效。',
                      })}

                      <br />
                      {intl.get({
                        id: 'code-assets.components.importProjectListModal.ReadFailedDueToSystem',
                        defaultMessage:
                          '3.系统原因导致读取失败。请您尝试刷新页面，如果问题仍旧存在请点击右下角的帮助入口咨询技术支持。',
                      })}
                    </div>
                  )}
                </div>
              }
            />
          </div>
          {isTooLarge && tableDataLoaded && (
            <div className="more-list-help">
              <YunxiaoIcon type="warning-fill" />{' '}
              <span>
                {intl.get({
                  id: 'code-assets.components.importProjectListModal.TheNumberOfCodeLibraries.1',
                  defaultMessage: '代码库数量超限，部分仓库未显示加载，建议使用本地',
                })}
                <a href={docs('importTool')} target="_blank" rel="noreferrer">
                  {intl.get({
                    id: 'code-assets.components.importProjectListModal.ImportTool',
                    defaultMessage: '导入工具',
                  })}
                </a>
                {intl.get({
                  id: 'code-assets.components.importProjectListModal.ImportOperations',
                  defaultMessage: '操作导入',
                })}
              </span>
            </div>
          )}

          <div
            className={`${prefix}-table ${selectedRowKeys.length ? 'selected' : ''}`}
            style={{ display: showTable ? 'block' : 'none' }}
          >
            <Table
              primaryKey="import_repo_id"
              dataSource={curList.slice(0, maxListLength)}
              rowSelection={{
                titleProps: () => {
                  return {
                    disabled: !curList.some((item) => item.import_status === 'not_import'),
                  };
                },
                selectedRowKeys,
                onChange: this.onChange,
                getProps: (record) => {
                  return {
                    disabled:
                      record.vcs_type === 'svn' ||
                      this.isInvalidRecord(repeatList, record.import_repo_id) ||
                      inValidateList.includes(record.import_repo_id) ||
                      ([STOPPED, FAIL].includes(record.import_status) && record.new_repo_id) ||
                      [IMPORTING, SUCCESS, WAITING, STOPPING].includes(record.import_status),
                  };
                },
                columnProps: () => {
                  return {
                    lock: 'none', // 组件内规则，只要有锁列，那么默认选择列左锁列
                  };
                },
                titleAddons: () => {
                  if (!selectedRowKeys.length) {
                    return null;
                  }
                  return (
                    <span className="op-container" key="op-container">
                      <span className="total-tip" style={{ position: 'relative', top: '2px' }}>
                        {intl.get(
                          {
                            id: 'code-assets.components.importProjectListModal.SelectedrowkeyslengthIsSelected',
                            defaultMessage: '已选择 {selectedRowKeysLength} 项',
                          },

                          { selectedRowKeysLength: selectedRowKeys.length },
                        )}
                      </span>
                      <Button
                        text
                        onClick={() => {
                          track(trackMap[accountInfo.platform_type].importList);
                          this.importList(selectedRowKeys);
                        }}
                      >
                        <YunxiaoIcon type="import-module-line" />
                        {intl.get({
                          id: 'code-assets.components.importProjectListModal.Import',
                          defaultMessage: '导入',
                        })}
                      </Button>
                    </span>
                  );
                },
              }}
              loading={isLoadingTable}
              fixedHeader
              maxBodyHeight={`calc(100vh - ${isTooLarge ? '260px' : '200px'})`}
            >
              <Table.Column
                className={showRepoSize ? 'import-repo-name-size-col' : 'import-repo-name-col'}
                title={tableHeaders.import_repo_name}
                cell={this.renderImportRepoName}
                dataIndex="import_repo_name"
              />

              <Table.Column
                className="new-repo-name-col"
                title={tableHeaders.new_repo_name}
                dataIndex="new_repo_name"
                cell={this.renderNewImportName}
              />

              <Table.Column
                className="visibility-level-col"
                title={tableHeaders.visibility_level}
                cell={this.renderVisibilityLevel}
                dataIndex="visibility_level"
              />

              {showRepoSize && (
                <Table.Column
                  className="import-repo-size-col"
                  title={tableHeaders.import_repo_size}
                  cell={this.renderImportRepoSize}
                  dataIndex="import_repo_size"
                />
              )}

              <Table.Column
                className="import-status-col"
                title={tableHeaders.import_status}
                cell={this.renderStatus}
                dataIndex="import_status"
              />

              <Table.Column
                className="actions-col"
                title={tableHeaders.actions}
                cell={this.renderActions}
                dataIndex="actions"
              />
            </Table>
          </div>
        </div>
      </Modal>
    );
  }
}
